define(['../vendor/kobako/random.js'
    , '../vendor/kobako/pixi/sprites.js'
    , 'PIXI'
    , '../vendor/kobako/pixi/anime.js'
    , '../vendor/kobako/counter.js'
    , '../vendor/kobako/pixi/weapon.js'
], (rand, sps, PIXI, anm, Counter, Weapon) => {

    function rand_move_sprite(bound, stones, sprite) {
        const x = rand.rand_between(10, bound.width - sprite.width)
        const y = rand.rand_between(10, bound.height - sprite.height)
        sprite.x = x
        sprite.y = y
        if (sps.is_collided_with_stones(stones, sprite)) {
            return rand_move_sprite(bound, stones, sprite)
        } else {
            return sprite
        }
    }

    const spawner = {
        level_one: (texture_spawner) => {
            const result = new PIXI.Sprite(texture_spawner['monster1']())
            sps.enable_move(result)
            anm.enable(result)
            return result
        }
    }

    function direction_should_move(you, target) {
        if (Math.abs(target.x - you.x) >= Math.abs(target.y - you.y)) {// Move horizontally
            if (target.x - you.x < 0) {
                return 'left'
            } else {
                return 'right'
            }
        } else {// Move vertically
            if (target.y - you.y < 0) {
                return 'up'
            } else {
                return 'down'
            }
        }
    }

    function enable_update(m,  move_time = 60, speed = 4) {
        const move_time_counter = new Counter(move_time) //Move about 3s 
        const rest_counter = new Counter(40) // Stop about 2s
        let state = 'stop' // move and stop
        m.update = player => {
            if (state == 'move') {
                move_time_counter.update()
                if (!move_time_counter.is_over()) {
                    return
                }
                move_time_counter.reset()
                m.stop()
                state = 'stop'
                m.weapon.emit()
            } else if (state == 'stop') {
                rest_counter.update()
                if (!rest_counter.is_over()) {
                    return
                }
                rest_counter.reset()
                m.move(direction_should_move(m, player), speed)
                state = 'move'
            }
        }
    }

    function bullet1(facing, texture_spawner){
        const bullet = new PIXI.Sprite(texture_spawner.bullet1())
        sps.enable_move(bullet, 8)
        switch(facing){
            case 0: 
                bullet.move('up')
                break;
            case 1:
                bullet.move('right')
                break;
            case 2:
                bullet.move('down')
                break;
            case 3:
                bullet.move('left')
                break;
        }

        anm.loop_anime_sprite(bullet)
        bullet.set_ani('steady')
        return bullet
    }

    function enable_weapon(m, bullets, texture_spawner) {
        const weapon = {
            emit: () => {
		const b = bullet1(m.facing, texture_spawner)
		sps.attach(m, b)
                bullets.addChild(b)
            }
        }
        m.weapon = weapon
    }

    return {
        spawn_level_one_monsters(bound, stones, num, texture_spawner, bullets, booms) {
            const result = []
            for (let i = 0; i < num; i++) {
                const monster = spawner['level_one'](texture_spawner)
                rand_move_sprite(bound, stones, monster)
                enable_weapon(monster, bullets, texture_spawner)
                enable_update(monster)
                result.push(monster)
            }
            return result
        }
    }
})
